#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
练习题 61: 微服务架构框架设计
难度: ⭐⭐⭐⭐⭐
知识点: 微服务架构、服务发现、负载均衡、熔断器、分布式追踪
参考文件: 整个项目的架构设计思想
"""

import asyncio
import json
import time
import uuid
import hashlib
from abc import ABC, abstractmethod
from typing import Dict, List, Optional, Any, Callable, Union
from dataclasses import dataclass, field
from enum import Enum
import threading
import logging
from contextlib import asynccontextmanager
import aiohttp
from datetime import datetime, timedelta

def problem_description():
    """
    题目描述:
    设计并实现一个完整的微服务架构框架，包含服务注册与发现、
    负载均衡、熔断器、分布式追踪、配置管理等核心组件。
    
    要求:
    1. 服务注册与发现机制
    2. 多种负载均衡策略
    3. 熔断器模式实现
    4. 分布式链路追踪
    5. 配置中心集成
    6. 健康检查机制
    7. 服务网关功能
    8. 监控指标收集
    
    应用场景:
    - 大型分布式系统
    - 云原生应用
    - 高并发Web服务
    - 企业级应用架构
    """
    pass

# ============================================================================
# 核心数据结构
# ============================================================================

class ServiceStatus(Enum):
    """服务状态枚举"""
    HEALTHY = "healthy"
    UNHEALTHY = "unhealthy"
    UNKNOWN = "unknown"
    MAINTENANCE = "maintenance"

class LoadBalanceStrategy(Enum):
    """负载均衡策略"""
    ROUND_ROBIN = "round_robin"
    WEIGHTED_ROUND_ROBIN = "weighted_round_robin"
    LEAST_CONNECTIONS = "least_connections"
    RANDOM = "random"
    CONSISTENT_HASH = "consistent_hash"

@dataclass
class ServiceInstance:
    """服务实例信息"""
    service_id: str
    service_name: str
    host: str
    port: int
    weight: int = 1
    status: ServiceStatus = ServiceStatus.UNKNOWN
    metadata: Dict[str, Any] = field(default_factory=dict)
    last_heartbeat: Optional[datetime] = None
    connection_count: int = 0
    
    @property
    def address(self) -> str:
        return f"{self.host}:{self.port}"
    
    @property
    def url(self) -> str:
        return f"http://{self.host}:{self.port}"

@dataclass
class TraceContext:
    """分布式追踪上下文"""
    trace_id: str
    span_id: str
    parent_span_id: Optional[str] = None
    baggage: Dict[str, str] = field(default_factory=dict)
    
    @classmethod
    def new_trace(cls) -> 'TraceContext':
        trace_id = str(uuid.uuid4())
        span_id = str(uuid.uuid4())
        return cls(trace_id=trace_id, span_id=span_id)
    
    def new_span(self) -> 'TraceContext':
        return TraceContext(
            trace_id=self.trace_id,
            span_id=str(uuid.uuid4()),
            parent_span_id=self.span_id,
            baggage=self.baggage.copy()
        )

# ============================================================================
# 服务注册与发现
# ============================================================================

class ServiceRegistry(ABC):
    """服务注册中心接口"""
    
    @abstractmethod
    async def register(self, instance: ServiceInstance) -> bool:
        """注册服务实例"""
        pass
    
    @abstractmethod
    async def deregister(self, service_id: str) -> bool:
        """注销服务实例"""
        pass
    
    @abstractmethod
    async def discover(self, service_name: str) -> List[ServiceInstance]:
        """发现服务实例"""
        pass
    
    @abstractmethod
    async def heartbeat(self, service_id: str) -> bool:
        """发送心跳"""
        pass

class InMemoryServiceRegistry(ServiceRegistry):
    """内存服务注册中心实现"""
    
    def __init__(self, heartbeat_timeout: int = 30):
        self._services: Dict[str, ServiceInstance] = {}
        self._service_names: Dict[str, List[str]] = {}
        self._heartbeat_timeout = heartbeat_timeout
        self._lock = asyncio.Lock()
    
    async def register(self, instance: ServiceInstance) -> bool:
        """注册服务实例"""
        async with self._lock:
            # TODO: 实现服务注册逻辑
            pass
    
    async def deregister(self, service_id: str) -> bool:
        """注销服务实例"""
        async with self._lock:
            # TODO: 实现服务注销逻辑
            pass
    
    async def discover(self, service_name: str) -> List[ServiceInstance]:
        """发现服务实例"""
        async with self._lock:
            # TODO: 实现服务发现逻辑
            pass
    
    async def heartbeat(self, service_id: str) -> bool:
        """发送心跳"""
        async with self._lock:
            # TODO: 实现心跳处理逻辑
            pass
    
    async def cleanup_expired_services(self):
        """清理过期服务"""
        # TODO: 实现过期服务清理
        pass

# ============================================================================
# 负载均衡器
# ============================================================================

class LoadBalancer(ABC):
    """负载均衡器接口"""
    
    @abstractmethod
    async def select(self, instances: List[ServiceInstance], 
                    context: Optional[Dict[str, Any]] = None) -> Optional[ServiceInstance]:
        """选择服务实例"""
        pass

class RoundRobinLoadBalancer(LoadBalancer):
    """轮询负载均衡器"""
    
    def __init__(self):
        self._counters: Dict[str, int] = {}
        self._lock = threading.Lock()
    
    async def select(self, instances: List[ServiceInstance], 
                    context: Optional[Dict[str, Any]] = None) -> Optional[ServiceInstance]:
        """轮询选择实例"""
        if not instances:
            return None
        
        # TODO: 实现轮询负载均衡逻辑
        pass

class WeightedRoundRobinLoadBalancer(LoadBalancer):
    """加权轮询负载均衡器"""
    
    def __init__(self):
        self._current_weights: Dict[str, int] = {}
        self._lock = threading.Lock()
    
    async def select(self, instances: List[ServiceInstance], 
                    context: Optional[Dict[str, Any]] = None) -> Optional[ServiceInstance]:
        """加权轮询选择实例"""
        if not instances:
            return None
        
        # TODO: 实现加权轮询负载均衡逻辑
        pass

class ConsistentHashLoadBalancer(LoadBalancer):
    """一致性哈希负载均衡器"""
    
    def __init__(self, virtual_nodes: int = 150):
        self._virtual_nodes = virtual_nodes
        self._hash_ring: Dict[int, ServiceInstance] = {}
        self._lock = threading.Lock()
    
    def _hash(self, key: str) -> int:
        """计算哈希值"""
        return int(hashlib.md5(key.encode()).hexdigest(), 16)
    
    def _build_hash_ring(self, instances: List[ServiceInstance]):
        """构建哈希环"""
        # TODO: 实现哈希环构建逻辑
        pass
    
    async def select(self, instances: List[ServiceInstance], 
                    context: Optional[Dict[str, Any]] = None) -> Optional[ServiceInstance]:
        """一致性哈希选择实例"""
        if not instances:
            return None
        
        # TODO: 实现一致性哈希负载均衡逻辑
        pass

# ============================================================================
# 熔断器
# ============================================================================

class CircuitBreakerState(Enum):
    """熔断器状态"""
    CLOSED = "closed"
    OPEN = "open"
    HALF_OPEN = "half_open"

@dataclass
class CircuitBreakerConfig:
    """熔断器配置"""
    failure_threshold: int = 5  # 失败阈值
    timeout: int = 60  # 超时时间（秒）
    success_threshold: int = 3  # 半开状态成功阈值
    window_size: int = 100  # 滑动窗口大小

class CircuitBreaker:
    """熔断器实现"""
    
    def __init__(self, config: CircuitBreakerConfig):
        self._config = config
        self._state = CircuitBreakerState.CLOSED
        self._failure_count = 0
        self._success_count = 0
        self._last_failure_time = None
        self._request_count = 0
        self._lock = threading.Lock()
    
    def _should_attempt_reset(self) -> bool:
        """是否应该尝试重置"""
        # TODO: 实现重置判断逻辑
        pass
    
    def _record_success(self):
        """记录成功"""
        # TODO: 实现成功记录逻辑
        pass
    
    def _record_failure(self):
        """记录失败"""
        # TODO: 实现失败记录逻辑
        pass
    
    async def call(self, func: Callable, *args, **kwargs) -> Any:
        """通过熔断器调用函数"""
        with self._lock:
            if self._state == CircuitBreakerState.OPEN:
                if self._should_attempt_reset():
                    self._state = CircuitBreakerState.HALF_OPEN
                    self._success_count = 0
                else:
                    raise Exception("Circuit breaker is OPEN")
        
        try:
            # TODO: 实现函数调用和状态管理逻辑
            pass
        except Exception as e:
            # TODO: 实现异常处理逻辑
            pass

# ============================================================================
# 分布式追踪
# ============================================================================

class Tracer:
    """分布式追踪器"""
    
    def __init__(self):
        self._spans: Dict[str, Dict[str, Any]] = {}
        self._current_context: Optional[TraceContext] = None
    
    def start_trace(self, operation_name: str) -> TraceContext:
        """开始新的追踪"""
        # TODO: 实现追踪开始逻辑
        pass
    
    def start_span(self, operation_name: str, 
                  parent_context: Optional[TraceContext] = None) -> TraceContext:
        """开始新的span"""
        # TODO: 实现span开始逻辑
        pass
    
    def finish_span(self, context: TraceContext, 
                   tags: Optional[Dict[str, Any]] = None,
                   logs: Optional[List[Dict[str, Any]]] = None):
        """结束span"""
        # TODO: 实现span结束逻辑
        pass
    
    def inject_context(self, context: TraceContext) -> Dict[str, str]:
        """注入追踪上下文到HTTP头"""
        # TODO: 实现上下文注入逻辑
        pass
    
    def extract_context(self, headers: Dict[str, str]) -> Optional[TraceContext]:
        """从HTTP头提取追踪上下文"""
        # TODO: 实现上下文提取逻辑
        pass

# ============================================================================
# 配置管理
# ============================================================================

class ConfigManager:
    """配置管理器"""
    
    def __init__(self):
        self._configs: Dict[str, Any] = {}
        self._watchers: Dict[str, List[Callable]] = {}
        self._lock = asyncio.Lock()
    
    async def get_config(self, key: str, default: Any = None) -> Any:
        """获取配置"""
        # TODO: 实现配置获取逻辑
        pass
    
    async def set_config(self, key: str, value: Any):
        """设置配置"""
        # TODO: 实现配置设置逻辑
        pass
    
    async def watch_config(self, key: str, callback: Callable):
        """监听配置变化"""
        # TODO: 实现配置监听逻辑
        pass
    
    async def load_from_file(self, file_path: str):
        """从文件加载配置"""
        # TODO: 实现文件配置加载逻辑
        pass

# ============================================================================
# 健康检查
# ============================================================================

class HealthChecker:
    """健康检查器"""
    
    def __init__(self, check_interval: int = 10):
        self._check_interval = check_interval
        self._health_checks: Dict[str, Callable] = {}
        self._running = False
    
    def register_check(self, name: str, check_func: Callable):
        """注册健康检查"""
        # TODO: 实现健康检查注册逻辑
        pass
    
    async def check_health(self, instance: ServiceInstance) -> bool:
        """检查服务实例健康状态"""
        # TODO: 实现健康检查逻辑
        pass
    
    async def start_monitoring(self, registry: ServiceRegistry):
        """开始监控"""
        # TODO: 实现监控开始逻辑
        pass
    
    async def stop_monitoring(self):
        """停止监控"""
        # TODO: 实现监控停止逻辑
        pass

# ============================================================================
# 服务网关
# ============================================================================

class ServiceGateway:
    """服务网关"""
    
    def __init__(self, registry: ServiceRegistry, 
                 load_balancer: LoadBalancer,
                 tracer: Tracer):
        self._registry = registry
        self._load_balancer = load_balancer
        self._tracer = tracer
        self._circuit_breakers: Dict[str, CircuitBreaker] = {}
        self._routes: Dict[str, str] = {}
    
    def add_route(self, path: str, service_name: str):
        """添加路由"""
        # TODO: 实现路由添加逻辑
        pass
    
    async def route_request(self, path: str, method: str, 
                          headers: Dict[str, str], 
                          body: Optional[bytes] = None) -> Dict[str, Any]:
        """路由请求"""
        # TODO: 实现请求路由逻辑
        pass
    
    def _get_circuit_breaker(self, service_name: str) -> CircuitBreaker:
        """获取熔断器"""
        # TODO: 实现熔断器获取逻辑
        pass
    
    async def _forward_request(self, instance: ServiceInstance, 
                             path: str, method: str,
                             headers: Dict[str, str], 
                             body: Optional[bytes] = None) -> Dict[str, Any]:
        """转发请求"""
        # TODO: 实现请求转发逻辑
        pass

# ============================================================================
# 监控指标
# ============================================================================

@dataclass
class Metric:
    """监控指标"""
    name: str
    value: float
    timestamp: datetime
    tags: Dict[str, str] = field(default_factory=dict)

class MetricsCollector:
    """指标收集器"""
    
    def __init__(self):
        self._metrics: List[Metric] = []
        self._counters: Dict[str, float] = {}
        self._gauges: Dict[str, float] = {}
        self._histograms: Dict[str, List[float]] = {}
        self._lock = threading.Lock()
    
    def increment_counter(self, name: str, value: float = 1.0, 
                         tags: Optional[Dict[str, str]] = None):
        """增加计数器"""
        # TODO: 实现计数器增加逻辑
        pass
    
    def set_gauge(self, name: str, value: float, 
                 tags: Optional[Dict[str, str]] = None):
        """设置仪表盘"""
        # TODO: 实现仪表盘设置逻辑
        pass
    
    def record_histogram(self, name: str, value: float, 
                        tags: Optional[Dict[str, str]] = None):
        """记录直方图"""
        # TODO: 实现直方图记录逻辑
        pass
    
    def get_metrics(self) -> List[Metric]:
        """获取所有指标"""
        # TODO: 实现指标获取逻辑
        pass

# ============================================================================
# 微服务框架主类
# ============================================================================

class MicroserviceFramework:
    """微服务框架主类"""
    
    def __init__(self):
        self._registry = InMemoryServiceRegistry()
        self._load_balancer = RoundRobinLoadBalancer()
        self._tracer = Tracer()
        self._config_manager = ConfigManager()
        self._health_checker = HealthChecker()
        self._gateway = ServiceGateway(self._registry, self._load_balancer, self._tracer)
        self._metrics_collector = MetricsCollector()
        self._services: Dict[str, ServiceInstance] = {}
    
    async def register_service(self, service_name: str, host: str, port: int, 
                             weight: int = 1, metadata: Optional[Dict[str, Any]] = None) -> str:
        """注册服务"""
        # TODO: 实现服务注册逻辑
        pass
    
    async def deregister_service(self, service_id: str) -> bool:
        """注销服务"""
        # TODO: 实现服务注销逻辑
        pass
    
    async def call_service(self, service_name: str, path: str, method: str = "GET",
                          headers: Optional[Dict[str, str]] = None,
                          body: Optional[bytes] = None) -> Dict[str, Any]:
        """调用服务"""
        # TODO: 实现服务调用逻辑
        pass
    
    def set_load_balance_strategy(self, strategy: LoadBalanceStrategy):
        """设置负载均衡策略"""
        # TODO: 实现负载均衡策略设置逻辑
        pass
    
    async def start_health_monitoring(self):
        """开始健康监控"""
        # TODO: 实现健康监控开始逻辑
        pass
    
    async def get_service_metrics(self) -> Dict[str, Any]:
        """获取服务指标"""
        # TODO: 实现服务指标获取逻辑
        pass
    
    async def shutdown(self):
        """关闭框架"""
        # TODO: 实现框架关闭逻辑
        pass

async def demonstrate_microservice_framework():
    """
    演示微服务框架的功能
    """
    print("=== 微服务架构框架演示 ===")
    
    # 创建框架实例
    framework = MicroserviceFramework()
    
    # 注册服务
    print("\n=== 服务注册 ===")
    user_service_id = await framework.register_service(
        "user-service", "localhost", 8001, weight=2
    )
    order_service_id = await framework.register_service(
        "order-service", "localhost", 8002, weight=1
    )
    print(f"用户服务注册: {user_service_id}")
    print(f"订单服务注册: {order_service_id}")
    
    # 设置负载均衡策略
    print("\n=== 负载均衡配置 ===")
    framework.set_load_balance_strategy(LoadBalanceStrategy.WEIGHTED_ROUND_ROBIN)
    print("设置加权轮询负载均衡策略")
    
    # 开始健康监控
    print("\n=== 健康监控 ===")
    await framework.start_health_monitoring()
    print("健康监控已启动")
    
    # 模拟服务调用
    print("\n=== 服务调用 ===")
    try:
        response = await framework.call_service(
            "user-service", "/api/users/123", 
            "GET",
            headers={"Authorization": "Bearer token123"}
        )
        print(f"用户服务响应: {response}")
    except Exception as e:
        print(f"服务调用失败: {e}")
    
    # 获取服务指标
    print("\n=== 服务指标 ===")
    metrics = await framework.get_service_metrics()
    print(f"服务指标: {metrics}")
    
    # 关闭框架
    print("\n=== 框架关闭 ===")
    await framework.shutdown()
    print("微服务框架已关闭")

async def demonstrate_load_balancing():
    """
    演示负载均衡功能
    """
    print("\n=== 负载均衡器测试 ===")
    
    # 创建测试服务实例
    instances = [
        ServiceInstance("svc1", "test-service", "host1", 8001, weight=3),
        ServiceInstance("svc2", "test-service", "host2", 8002, weight=2),
        ServiceInstance("svc3", "test-service", "host3", 8003, weight=1),
    ]
    
    # 测试轮询负载均衡
    print("\n--- 轮询负载均衡 ---")
    round_robin_lb = RoundRobinLoadBalancer()
    for i in range(6):
        selected = await round_robin_lb.select(instances)
        print(f"第{i+1}次选择: {selected.address if selected else 'None'}")
    
    # 测试加权轮询负载均衡
    print("\n--- 加权轮询负载均衡 ---")
    weighted_lb = WeightedRoundRobinLoadBalancer()
    for i in range(12):
        selected = await weighted_lb.select(instances)
        print(f"第{i+1}次选择: {selected.address if selected else 'None'} (权重: {selected.weight if selected else 'N/A'})")
    
    # 测试一致性哈希负载均衡
    print("\n--- 一致性哈希负载均衡 ---")
    consistent_hash_lb = ConsistentHashLoadBalancer()
    test_keys = ["user123", "user456", "user789", "user123", "user456"]
    for key in test_keys:
        selected = await consistent_hash_lb.select(instances, {"key": key})
        print(f"键 '{key}' 选择: {selected.address if selected else 'None'}")

async def demonstrate_circuit_breaker():
    """
    演示熔断器功能
    """
    print("\n=== 熔断器测试 ===")
    
    # 创建熔断器
    config = CircuitBreakerConfig(failure_threshold=3, timeout=5)
    circuit_breaker = CircuitBreaker(config)
    
    # 模拟函数调用
    call_count = 0
    
    async def unreliable_service():
        nonlocal call_count
        call_count += 1
        if call_count <= 5:  # 前5次调用失败
            raise Exception(f"服务调用失败 (第{call_count}次)")
        return f"服务调用成功 (第{call_count}次)"
    
    # 测试熔断器
    for i in range(10):
        try:
            result = await circuit_breaker.call(unreliable_service)
            print(f"调用 {i+1}: 成功 - {result}")
        except Exception as e:
            print(f"调用 {i+1}: 失败 - {e}")
        
        # 等待一段时间
        await asyncio.sleep(0.1)

if __name__ == "__main__":
    async def main():
        # 运行所有演示
        await demonstrate_microservice_framework()
        await demonstrate_load_balancing()
        
        # 运行熔断器演示
        await demonstrate_circuit_breaker()
        
        print("\n=== 微服务架构最佳实践 ===")
        print("1. 服务拆分要合理，避免过度拆分")
        print("2. 实现完善的监控和日志系统")
        print("3. 使用熔断器防止级联故障")
        print("4. 实现优雅的服务降级机制")
        print("5. 保证数据一致性和事务处理")
        print("6. 实现自动化部署和运维")
        print("7. 考虑服务间的安全通信")
        print("8. 设计合理的API版本管理策略")
    
    asyncio.run(main())